/********************************************************************************
* @file    kv_sys.h
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-11-03
* @brief   KV键值系统
********************************************************************************/

#ifndef __KV_SYS_H__
#define __KV_SYS_H__

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>

/* Define --------------------------------------------------------------------*/
#ifdef LISUN_SDK
#include "ls_syscfg.h"

// KV系统总共可以使用N字节
#define LS_KV_SUM_SIZE                  (LS_FLASH_PAGE_SIZE * (LS_FLASH_KV_PAGE - 1))
#else
#define LS_FLASH_PAGE_SIZE              (512)
#define LS_FLASH_KV_PAGE                (3)
#define LS_FLASH_WRITE_BYTE_ABILITY     (4) // flash最小写入颗粒

// KV系统总共可以使用N字节
#define LS_KV_SUM_SIZE                  (LS_FLASH_PAGE_SIZE * (LS_FLASH_KV_PAGE - 1))

#define LS_KV_BASE_ADDR                 (0x00) // 自行修改
#define LS_KV_BACK_ADDR                 (LS_KV_BASE_ADDR + LS_KV_SUM_SIZE)

#endif

#define KV_SYS_PACK_HEAD    0xFEEF9581
/* Public Struct -------------------------------------------------------------*/

// 仅适用终极版 FE EF 95 81 KEYID is_en len data0 data1 sum
typedef struct __attribute__((packed)){
    uint32_t head;                                   // 头字节 0xFEEF9581(固有)
    uint8_t  sum;                                    // 校验和
    uint8_t  len;                                    // 实际长度(包含key_id+is_en+buff)
    uint16_t key_id;                                 // KEY ID [1,254]  0和255不能使用
#if LS_FLASH_WRITE_BYTE_ABILITY == 1
    uint8_t  is_en;                                  // 是否有效 0--无效 FF--有效
#elif LS_FLASH_WRITE_BYTE_ABILITY == 4
    uint32_t is_en;                                  // 是否有效 0--无效 FF--有效
#endif
    uint8_t  *buff;                                  // 实际数据指针
} kv_sys_m_t;

/* Public Function Prototypes -----------------------------------------------*/

int kv_gc_env(void);
void kv_gc_check(void);
void* kv_get_env(uint16_t key_id);
bool kv_del_env(uint16_t key_id);
bool kv_set_env(uint16_t key_id, void *data, uint8_t len);
#endif
